﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApExportPaintFilesApp
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Resources;
using System.Text;
using System.Timers;
using System.Windows.Forms;
using System.Xml;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands;

public class CApExportPaintFilesApp
{
  private TxRobot m_robot;
  private XmlTextWriter m_textWriter;
  private TxSimulationPlayer m_simPlayer;
  private bool m_operationStarted;
  private ITxOperation m_op;
  private TxFrame m_dynamicRefFrame;
  private TxTransformation m_dynamicRefFrameStartTrans;
  private ITxOperation lastOperationInTheCompound;
  private bool m_isFirstNode = true;
  private double m_lastTime;
  private const double EPSILON = 1E-05;
  private bool m_isFrameElementStillOpen;
  private ResourceManager m_resourceManager;
  private const string CHANGE_BRUSH_TRIGGER_PREFIX_STR = "Brush";
  private const int SIMULATION_TIMEOUT = 120;

  public CApExportPaintFilesApp()
  {
    this.m_simPlayer = new TxSimulationPlayer(false, true);
    this.m_resourceManager = new ResourceManager("DnProcessSimulateCommands.ExportPaintFiles.StringTable", this.GetType().Assembly);
  }

  public bool ExportJT(TxObjectList parts, string path)
  {
    bool flag = true;
    TxJtExportDataEx txJtExportDataEx = new TxJtExportDataEx(path);
    txJtExportDataEx.TargetJtFormat = (TxJtExportDataEx.TxJtFormatEx) 0;
    txJtExportDataEx.ShouldIncludeLogisticManipulators = true;
    txJtExportDataEx.ShouldAddRootNode = true;
    try
    {
      new TxDocumentEx().SaveCollectionToJtAssembly(parts, txJtExportDataEx);
    }
    catch (Exception ex)
    {
      flag = false;
    }
    return flag;
  }

  public void InitLastOperationInTheCompound(ITxRoboticOrderedCompoundOperation op)
  {
    if (op == null)
      return;
    ITxTypeFilter itxTypeFilter = (ITxTypeFilter) new TxNoTypeFilter();
    TxObjectList directDescendants = ((ITxObjectCollection) op).GetDirectDescendants(itxTypeFilter);
    if (((Collection<ITxObject>) directDescendants).Count <= 0)
      return;
    this.lastOperationInTheCompound = ((Collection<ITxObject>) directDescendants)[((Collection<ITxObject>) directDescendants).Count - 1] as ITxOperation;
  }

  public bool GenerateSimFile(
    ITxRoboticOrderedCompoundOperation op,
    double timeInterval,
    bool simLineSimulation,
    string path,
    ref ArrayList errors)
  {
    bool simFile = true;
    this.m_op = (ITxOperation) op;
    this.m_lastTime = 0.0;
    this.m_isFrameElementStillOpen = false;
    this.m_isFirstNode = true;
    this.m_robot = op.Robot as TxRobot;
    ITxOperation itxOperation = (ITxOperation) op;
    this.InitLastOperationInTheCompound(op);
    if (simLineSimulation)
    {
      TxOperationRoot operationRoot = TxApplication.ActiveDocument.OperationRoot;
      TxTypeFilter txTypeFilter = new TxTypeFilter();
      txTypeFilter.AddIncludedType(typeof (ITxOperation));
      ITxOperation directDescendant = ((Collection<ITxObject>) operationRoot.GetDirectDescendants((ITxTypeFilter) txTypeFilter))[0] as ITxOperation;
      if (new TxOperationEx(directDescendant).IsLineOperation())
        itxOperation = directDescendant;
      else
        simFile = false;
      if (simFile)
      {
        bool flag = false;
        TxRoboticParam parameter = ((ITxRoboticOperation) op).GetParameter("DYNAMIC_REFERENCE_FRAME");
        if (parameter != null && parameter is TxRoboticTxObjectParam)
        {
          ITxObject itxObject = (parameter as TxRoboticTxObjectParam).Value;
          if (itxObject != null && itxObject is TxFrame)
          {
            this.m_dynamicRefFrame = itxObject as TxFrame;
            this.m_dynamicRefFrameStartTrans = this.m_dynamicRefFrame.AbsoluteLocation;
            flag = true;
          }
        }
        if (!flag)
        {
          string str = this.m_resourceManager.GetString("GENERATE_PAINT_FILES_CMD_NAME");
          if (TxMessageBox.Show(this.m_resourceManager.GetString("SIM_FILE_EXPORT_NO_DYNAMIC_REF_FRAME_ERR_MSG"), str, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
            simFile = false;
        }
      }
    }
    if (simFile)
    {
      TxPaintGun txPaintGun = (TxPaintGun) null;
      TxObjectList mountedTools = this.m_robot.MountedTools;
      if (mountedTools != null && ((Collection<ITxObject>) mountedTools).Count > 0)
        txPaintGun = ((Collection<ITxObject>) mountedTools)[0] as TxPaintGun;
      if (txPaintGun == null)
      {
        simFile = false;
      }
      else
      {
        this.m_textWriter = new XmlTextWriter(path, (Encoding) null);
        this.m_textWriter.WriteStartDocument();
        this.m_textWriter.WriteStartElement("Motion");
        TxSimulationPlayer simulationPlayer = new TxSimulationPlayer(false, true);
        try
        {
          simulationPlayer.AskUserForReset(true);
          simulationPlayer.IsAutomaticErrorOutputEnabled = false;
          this.m_simPlayer.SignificantTimeReached += new TxSimulationPlayer_SignificantTimeReachedEventHandler(this.onSignificantTimeReached);
          txPaintGun.Opened += new TxPaintGun_OpenedEventHandler(this.paintGun_Opened);
          txPaintGun.Closed += new TxPaintGun_ClosedEventHandler(this.paintGun_Closed);
          txPaintGun.BrushChanged += new TxPaintGun_BrushChangedEventHandler(this.paintGun_BrushChanged);
          System.Timers.Timer timer = new System.Timers.Timer(120000.0);
          if (simLineSimulation)
          {
            this.m_simPlayer.OperationStartedForward += new TxSimulationPlayer_OperationStartedForwardEventHandler(this.onOperationStartedForward);
            this.m_simPlayer.OperationEndedForward += new TxSimulationPlayer_OperationEndedForwardEventHandler(this.onOperationEndedForward);
            timer.Elapsed += new ElapsedEventHandler(this.clock_Elapsed);
            timer.Start();
          }
          else
            this.m_operationStarted = true;
          this.m_simPlayer.SetOperation(itxOperation);
          this.m_simPlayer.TimeInterval = timeInterval;
          this.m_simPlayer.PlayWithoutRefresh();
          this.m_simPlayer.SignificantTimeReached -= new TxSimulationPlayer_SignificantTimeReachedEventHandler(this.onSignificantTimeReached);
          txPaintGun.Opened -= new TxPaintGun_OpenedEventHandler(this.paintGun_Opened);
          txPaintGun.Closed -= new TxPaintGun_ClosedEventHandler(this.paintGun_Closed);
          txPaintGun.BrushChanged -= new TxPaintGun_BrushChangedEventHandler(this.paintGun_BrushChanged);
          if (simLineSimulation)
          {
            this.m_simPlayer.OperationStartedForward -= new TxSimulationPlayer_OperationStartedForwardEventHandler(this.onOperationStartedForward);
            this.m_simPlayer.OperationEndedForward -= new TxSimulationPlayer_OperationEndedForwardEventHandler(this.onOperationEndedForward);
            timer.Stop();
            timer.Elapsed -= new ElapsedEventHandler(this.clock_Elapsed);
          }
          this.m_simPlayer.IsAutomaticErrorOutputEnabled = true;
          List<string> errorsAndTraces = this.m_simPlayer.GetErrorsAndTraces((TxSimulationErrorType) 256 /*0x0100*/);
          if (errorsAndTraces.Count > 0)
            errors.AddRange((ICollection) errorsAndTraces);
          this.m_simPlayer.Rewind();
          this.m_simPlayer.ResetToDefaultSetting();
        }
        catch (Exception ex)
        {
          simFile = false;
        }
        finally
        {
          simulationPlayer.IsAutomaticErrorOutputEnabled = true;
        }
        this.WriteEndFrameElement();
        this.m_textWriter.WriteEndElement();
        this.m_textWriter.WriteEndDocument();
        this.m_textWriter.Close();
      }
    }
    return simFile;
  }

  private void clock_Elapsed(object sender, ElapsedEventArgs e)
  {
    (sender as System.Timers.Timer).Stop();
    if (this.m_operationStarted)
      return;
    string str = this.m_resourceManager.GetString("GENERATE_PAINT_FILES_CMD_NAME");
    if (TxMessageBox.Show(this.m_resourceManager.GetString("SIM_FILE_EXPORT_TIMEOUT_ERR_MSG"), str, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
      this.m_simPlayer.Stop();
    else
      (sender as System.Timers.Timer).Start();
  }

  private void paintGun_Closed(object sender, TxPaintGun_ClosedEventArgs args)
  {
    this.WriteTriggerFrame("Brush 2");
  }

  private void paintGun_Opened(object sender, TxPaintGun_OpenedEventArgs args)
  {
  }

  private void paintGun_BrushChanged(object sender, TxPaintGun_BrushChangedEventArgs args)
  {
    this.WriteTriggerFrame("Brush " + args.BrushName);
  }

  private void WriteStartFrameElement()
  {
    if (!this.m_isFrameElementStillOpen)
      this.m_textWriter.WriteStartElement("Frame");
    this.m_isFrameElementStillOpen = true;
  }

  private void WriteEndFrameElement()
  {
    if (this.m_isFrameElementStillOpen)
      this.m_textWriter.WriteEndElement();
    this.m_isFrameElementStillOpen = false;
  }

  private void onSignificantTimeReached(
    object sender,
    TxSimulationPlayer_SignificantTimeReachedEventArgs args)
  {
    if (!this.m_operationStarted || !this.m_isFirstNode && this.m_simPlayer.CurrentTime - this.m_lastTime <= 1E-05)
      return;
    if (this.m_isFirstNode)
      this.m_isFirstNode = false;
    else
      this.WriteEndFrameElement();
    this.WriteStartFrameElement();
    this.WriteTimeAndPosition();
  }

  private void WriteTriggerFrame(string triggerString)
  {
    if (this.m_isFirstNode)
    {
      this.m_isFirstNode = false;
      this.WriteStartFrameElement();
      this.WriteTimeAndPosition();
      this.WriteTriggerInformation(triggerString);
    }
    else if (this.m_simPlayer.CurrentTime - this.m_lastTime > 1E-05)
    {
      this.WriteEndFrameElement();
      this.WriteStartFrameElement();
      this.WriteTimeAndPosition();
      this.WriteTriggerInformation(triggerString);
    }
    else
    {
      this.WriteTriggerInformation(triggerString);
      this.WriteEndFrameElement();
    }
  }

  private void WriteTriggerInformation(string triggerString)
  {
    this.m_textWriter.WriteStartElement("Trigger");
    this.m_textWriter.WriteStartAttribute("type");
    this.m_textWriter.WriteValue(triggerString);
    this.m_textWriter.WriteEndAttribute();
    this.m_textWriter.WriteEndElement();
  }

  private void WriteTimeAndPosition()
  {
    double currentTime = this.m_simPlayer.CurrentTime;
    TxObjectList mountedTools = this.m_robot.MountedTools;
    if (mountedTools == null || ((Collection<ITxObject>) mountedTools).Count <= 0 || !(((Collection<ITxObject>) mountedTools)[0] is TxPaintGun paintGun))
      return;
    TxTransformation relativeTipFrameTrans = this.GetRelativeTipFrameTrans(paintGun);
    this.m_textWriter.WriteStartElement("Time");
    this.m_textWriter.WriteStartAttribute("t");
    this.m_textWriter.WriteValue(currentTime);
    this.m_lastTime = currentTime;
    this.m_textWriter.WriteEndAttribute();
    this.m_textWriter.WriteEndElement();
    this.m_textWriter.WriteStartElement("Translation");
    this.m_textWriter.WriteStartAttribute("x");
    this.m_textWriter.WriteValue(relativeTipFrameTrans.Translation.X);
    this.m_textWriter.WriteEndAttribute();
    this.m_textWriter.WriteStartAttribute("y");
    this.m_textWriter.WriteValue(relativeTipFrameTrans.Translation.Y);
    this.m_textWriter.WriteEndAttribute();
    this.m_textWriter.WriteStartAttribute("z");
    this.m_textWriter.WriteValue(relativeTipFrameTrans.Translation.Z);
    this.m_textWriter.WriteEndAttribute();
    this.m_textWriter.WriteEndElement();
    this.m_textWriter.WriteStartElement("RPY");
    this.m_textWriter.WriteStartAttribute("roll");
    this.m_textWriter.WriteValue(relativeTipFrameTrans.RotationRPY_XYZ.Z * (180.0 / Math.PI));
    this.m_textWriter.WriteEndAttribute();
    this.m_textWriter.WriteStartAttribute("pitch");
    this.m_textWriter.WriteValue(relativeTipFrameTrans.RotationRPY_XYZ.Y * (180.0 / Math.PI));
    this.m_textWriter.WriteEndAttribute();
    this.m_textWriter.WriteStartAttribute("yaw");
    this.m_textWriter.WriteValue(relativeTipFrameTrans.RotationRPY_XYZ.X * (180.0 / Math.PI));
    this.m_textWriter.WriteEndAttribute();
    this.m_textWriter.WriteEndElement();
  }

  private TxTransformation GetRelativeTipFrameTrans(TxPaintGun paintGun)
  {
    TxTransformation relativeTipFrameTrans = paintGun.GunTip.AbsoluteLocation;
    if (TxFrame.op_Inequality(this.m_dynamicRefFrame, (ITxObject) null) && TxTransformation.op_Inequality(this.m_dynamicRefFrameStartTrans, (TxTransformation) null))
      relativeTipFrameTrans = TxTransformation.op_Multiply(TxTransformation.op_Multiply(this.m_dynamicRefFrame.AbsoluteLocation, this.m_dynamicRefFrameStartTrans.Inverse).Inverse, relativeTipFrameTrans);
    return relativeTipFrameTrans;
  }

  private bool GetPaintGunState(TxPaintGun paintGun)
  {
    bool paintGunState = false;
    TxFrame gunTip = paintGun.GunTip;
    if (TxFrame.op_Inequality(gunTip, (ITxObject) null))
    {
      TxTypeFilter txTypeFilter = new TxTypeFilter(typeof (TxManipulator));
      if (((Collection<ITxObject>) gunTip.GetDirectAttachmentDescendants((ITxTypeFilter) txTypeFilter)).Count > 0)
        paintGunState = true;
    }
    return paintGunState;
  }

  private void onOperationStartedForward(
    object sender,
    TxSimulationPlayer_OperationStartedForwardEventArgs args)
  {
    if (args.Operation != this.m_op)
      return;
    this.m_operationStarted = true;
  }

  private void onOperationEndedForward(
    object sender,
    TxSimulationPlayer_OperationEndedForwardEventArgs args)
  {
    ITxOperation operation = args.Operation;
    if (operation != this.m_op && operation != this.lastOperationInTheCompound || !this.m_operationStarted)
      return;
    this.m_simPlayer.Stop();
  }
}
